package com.leyou.item.service.impl.goods;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exception.LyException;
import com.leyou.common.pojo.PageResult;
import com.leyou.common.utils.BeanHelper;
import com.leyou.item.dto.SkuDTO;
import com.leyou.item.dto.SpuDTO;
import com.leyou.item.dto.SpuDetailDTO;
import com.leyou.item.entity.*;

import com.leyou.item.service.*;
import com.sun.xml.internal.ws.api.model.CheckedException;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.sql.SQLException;
import java.util.Collection;
import java.util.List;

import java.util.stream.Collectors;

import static com.leyou.common.constants.MQConstants.Exchange.ITEM_EXCHANGE_NAME;
import static com.leyou.common.constants.MQConstants.RoutingKey.ITEM_DOWN_KEY;
import static com.leyou.common.constants.MQConstants.RoutingKey.ITEM_UP_KEY;


@Service
public class GoodsService {
    @Autowired
    private AmqpTemplate amqpTemplate;
    @Autowired
    private TbSkuService skuService;
    @Autowired
    private TbSpuDetailService spuDetailService;
    @Autowired
    private TbBrandService brandService;
    @Autowired
    private TbSpuService spuService;
    @Autowired
    private CategoryService categoryService;

    public PageResult<SpuDTO> findSpuByPage(Integer page, Integer rows, String key, Boolean saleable) {
        IPage<TbSpu> iPage = new Page<>(page, rows);
        QueryWrapper<TbSpu> queryWrapper = new QueryWrapper();
        if (!StringUtils.isEmpty(key))
            queryWrapper.lambda().eq(TbSpu::getName, key);
        if (saleable != null)
            queryWrapper.lambda().eq(TbSpu::getSaleable, saleable);
        queryWrapper.lambda().orderByDesc(TbSpu::getUpdateTime);
        IPage<TbSpu> page1 = spuService.page(iPage, queryWrapper);
        if (page1 == null || CollectionUtils.isEmpty(page1.getRecords()))
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        List<SpuDTO> spuDTOs = BeanHelper.copyWithCollection(page1.getRecords(), SpuDTO.class);
        handleBrandAndCategoryName(spuDTOs);
        return new PageResult<>(page1.getTotal(), (int) page1.getPages(), spuDTOs);
    }

    private void handleBrandAndCategoryName(List<SpuDTO> list) {
        for (SpuDTO spuDTO : list) {
            List<Long> categorys = spuDTO.getCategorys();
            Collection<Category> tbCategoryCollection = categoryService.listByIds(categorys);//得到分类目录集合
            String categoryName = tbCategoryCollection.stream().map(Category::getName).collect(Collectors.joining("/"));
            spuDTO.setCategoryName(categoryName);
            //商品品牌
            Long brandId = spuDTO.getBrandId();
            TbBrand brand = brandService.getById(brandId);
            spuDTO.setBrandName(brand.getName());
        }
    }

    @Transactional
    public void updateSaleable(Long id, Boolean saleable) {
        TbSpu tbSpu = new TbSpu();
        tbSpu.setId(id);
        tbSpu.setSaleable(saleable);
        boolean b = spuService.updateById(tbSpu);
        if (!b)
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        UpdateWrapper<TbSku> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().set(TbSku::getEnable, saleable).eq(TbSku::getSpuId, id);
        boolean bSkuUpdate = skuService.update(updateWrapper);
        if (!bSkuUpdate) {
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }

        // 发送mq消息
        String key = saleable ? ITEM_UP_KEY : ITEM_DOWN_KEY;
        amqpTemplate.convertAndSend(ITEM_EXCHANGE_NAME, key, id);//routing_key
    }

    @Transactional(rollbackFor = Exception.class)
    public void saveGoods(SpuDTO spuDTO) {
            TbSpu tbSpu = BeanHelper.copyProperties(spuDTO, TbSpu.class);
        boolean save = spuService.save(tbSpu);
        if (!save)
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        Long id = tbSpu.getId();//save后mybaits自己查询添加
        //Tb_detail
        SpuDetailDTO spuDetail = spuDTO.getSpuDetail();
        TbSpuDetail tbSpuDetail = BeanHelper.copyProperties(spuDetail, TbSpuDetail.class);
        tbSpuDetail.setSpuId(id);
        boolean save1 = spuDetailService.save(tbSpuDetail);
        if (!save1)
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
//保存sku
        List<SkuDTO> skus = spuDTO.getSkus();
        if (!CollectionUtils.isEmpty(skus)) {
            List<TbSku> tbSkus = BeanHelper.copyWithCollection(skus, TbSku.class);
            tbSkus.forEach(tbSku -> tbSku.setSpuId(id));
            boolean b = skuService.saveBatch(tbSkus);
            if (!b)
                throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
            /*
            *         //保存sku信息
        List<SkuDTO> skus = spuDTO.getSkus();
        if(!CollectionUtils.isEmpty(skus)){
            List<TbSku> tbSkuList = skus.stream().map(skuDTO -> {
                skuDTO.setSpuId(spuId);
                return BeanHelper.copyProperties(skuDTO, TbSku.class);
            }).collect(Collectors.toList());
            boolean bSku = skuService.saveBatch(tbSkuList);
            * */
        } else {
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }
    }

    public SpuDetailDTO findSpuDetailById(Long id) {
        TbSpuDetail spuDetail = spuDetailService.getById(id);//spu和Detail表同id
        if (spuDetail == null) {
            throw new LyException(ExceptionEnum.GOODS_DETAIL_NOT_FOUND);
        }
        return BeanHelper.copyProperties(spuDetail, SpuDetailDTO.class);

    }

    public List<SkuDTO> findSkuListBySpuId(Long id) {
        QueryWrapper<TbSku> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TbSku::getSpuId, id);
        List<TbSku> list = skuService.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            // throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        List<SkuDTO> skuDTOS = BeanHelper.copyWithCollection(list, SkuDTO.class);

        return skuDTOS;
    }

    @Transactional(rollbackFor = Exception.class)
    public void updateGoods(SpuDTO spuDTO) {
        Long spuId = spuDTO.getId();
        if (spuId == null) {
            throw new LyException(ExceptionEnum.INVALID_PARAM_ERROR);
        }
        //删sku和添加sku
        QueryWrapper<TbSku> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TbSku::getSpuId, spuId);
        List<TbSku> list = skuService.list(queryWrapper);
        if (!CollectionUtils.isEmpty(list)) {
            UpdateWrapper<TbSku> skuUpdateWrapper = new UpdateWrapper<>();
            skuUpdateWrapper.lambda().eq(TbSku::getSpuId, spuId);
            boolean remove = skuService.remove(skuUpdateWrapper);
            if (!remove) {
                throw new LyException(ExceptionEnum.DELETE_OPERATION_FAIL);
            }
        }
        List<SkuDTO> skus = spuDTO.getSkus();
        if (!CollectionUtils.isEmpty(skus)) {
            List<TbSku> tbSkus = BeanHelper.copyWithCollection(skus, TbSku.class);
            tbSkus.forEach(tbSku -> tbSku.setSpuId(spuId));
            boolean b = skuService.saveBatch(tbSkus);
            if (!b)
                throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        } else {
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }
        //更新spu
        TbSpu tbSpu = BeanHelper.copyProperties(spuDTO, TbSpu.class);
        //tbSpu.setCreateTime(null);
        //tbSpu.setUpdateTime(null);
        boolean bSpu = spuService.updateById(tbSpu);
        if (!bSpu) {
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }
        //更新spuDetail
        SpuDetailDTO spuDetail = spuDTO.getSpuDetail();
        TbSpuDetail tbSpuDetail = BeanHelper.copyProperties(spuDetail, TbSpuDetail.class);
        tbSpuDetail.setSpuId(spuId);
        // tbSpuDetail.setCreateTime(null);
        //tbSpuDetail.setUpdateTime(null);
        boolean bSpuDetail = spuDetailService.updateById(tbSpuDetail);
        if (!bSpuDetail) {
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }
    }

    public SpuDTO findSpuById(Long spuId) {
        TbSpu tbSpu = spuService.getById(spuId);
        if (tbSpu == null) {
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        return BeanHelper.copyProperties(tbSpu, SpuDTO.class);
    }
}
